package object;

import object.Sprite;
import utilities.ImageLoader;
import utilities.TileManager;
import core.PlayState;
import java.awt.Rectangle;
/**
 * Class containing information related to the Player
 *
 */

public final class Player extends Sprite
{
    private static double DURATION=0.5;
    private static final int NOT_JUMPING=0;
    private static final int RISING=1;
    private static final int FALLING=2;
    private static final int MAX_UP_STEPS=8;

    private TileManager tileManager;

    private PlayState playState;

    private boolean isFacingRight;
    private boolean isStill;

    private int playerForm=1;
    private int period;
    private int moveSize;
    private int vertMoveMode;
    private int vertStep;
    private int upCount;
    private int xWorld,yWorld;

    //Creates a new Player with the adeafult animation and places it on a tile
    public Player(int width, int height,int brickMvSz,TileManager tm,ImageLoader imLd,int p,PlayState ps)
    {
        super(width/2,height/2,width,height,imLd,"runningRight1");
        moveSize=brickMvSz;
        tileManager=tm;
        period=p;
        setStep(0,0);

        isFacingRight=true;
        isStill=true;

        locy=tileManager.findFloor(locx+getWidth()/2)-getHeight();
        xWorld=locx;
        yWorld=locy;

        vertMoveMode=NOT_JUMPING;
        vertStep=tileManager.getTileHeight()/2;
        upCount=0;

        playState=ps;
    }

    //Updates the Player's animation
    public void updateSprite()
    {
        if (!isStill)
        {
            if (isFacingRight)
                xWorld+=moveSize;
            else
                xWorld-=moveSize;
            if (vertMoveMode==NOT_JUMPING)
                checkIfFalling();
        }

        if (vertMoveMode==RISING)
            updateJumping();
        else
            if (vertMoveMode==FALLING)
                updateFalling();

        super.updateSprite();
    }

    //Updates the Player's animation during jumping
    private void updateJumping()
    { 
        if (upCount==MAX_UP_STEPS)
        {
            vertMoveMode=FALLING;
            upCount=0;
        }
        else
        {
            int y=tileManager.checkTileUp(xWorld+(getWidth()/2),yWorld-vertStep,vertStep);
            if (y==0)
            {
                vertMoveMode=FALLING;
                upCount=0;
            }
            else
            {
                translate(0,-y);
                yWorld-=y;
                upCount++;
            }
        }
    }

    //Updates the Player's animation in the case it's falling down
    private void updateFalling()
    {
        //setImage("falling");
        int y=tileManager.checkTileDown(xWorld+(getWidth()/2),yWorld+getHeight()+vertStep,vertStep);
        if (y==0)
            finishJumping();
        else
        {
            translate(0,y);
            yWorld+=y;
        }
        
    }

    //If the Player has finished the jump, set it's animation to running
    private void finishJumping()
    {
        vertMoveMode=NOT_JUMPING;
        upCount=0;

        if (isStill)
        {
            switch (playerForm)
            {
                case 1: if (isFacingRight)
                            setImage("runningRight1");
                        else
                            setImage("runningLeft1");
                        break;
                case 2: if (isFacingRight)
                            setImage("runningRight2");
                        else
                            setImage("runningLeft2");
                        break;
                case 3: if (isFacingRight)
                            setImage("runningRight3");
                        else
                            setImage("runningLeft3");
                        break;
                default: if (isFacingRight)
                            setImage("runningRight1");
                        else
                            setImage("runningLeft1");
                        break;
            }
        }
    }

    //Check for collisions
    public boolean collisionDetection()
    {
        if (isStill)
            return false;

        int temp;
        if (isFacingRight)
            temp=xWorld+moveSize;
        else
            temp=xWorld-moveSize;

        int xNear=temp+getWidth()/2;
        int yNear=yWorld+(int)(getHeight()*0.8);

        return tileManager.checkTile(xNear,yNear);
    }

    //check if the Sprite will fall down if standing above the selected tile
    private void checkIfFalling()
    {
        int y=tileManager.checkTileDown( xWorld+(getWidth()/2),yWorld+getHeight()+vertStep, vertStep);
        if (y!=0)
            vertMoveMode=FALLING;
    }

    //move the Player to the left
    public void moveLeft()
    {
        switch(playerForm)
        {
            case 1: setImage("runningLeft1"); break;
            case 2: setImage("runningLeft2"); break;
            case 3: setImage("runningLeft3"); break;
            default: setImage("runningLeft1"); break;
        }
        loopImage(period,DURATION);
        isFacingRight=false;
        isStill=false;
    }

    //move the Player to the right
    public void moveRight()
    {
        switch(playerForm)
        {
            case 1: setImage("runningRight1"); break;
            case 2: setImage("runningRight2"); break;
            case 3: setImage("runningRight3"); break;
            default: setImage("runningRight1"); break;
        }
        loopImage(period,DURATION);
        isFacingRight=true;
        isStill=false;
    }

    public void breakdance()
    {
//        switch(playerForm)
//        {
//            case 1: setImage("runningRight1"); break;
//            case 2: setImage("runningRight2"); break;
//            default: setImage("runningRight1"); break;
//        }
        if (playerForm==2)
        {
            setImage("breakdance");
            loopImage(period,DURATION);
        }
        isFacingRight=true;
        isStill=false;
    }

    public void dance()
    {
        if (playerForm==2)
        {
            setImage("dance");
            loopImage(period,DURATION);
        }
        isFacingRight=true;
        isStill=false;
    }

    public void stayStill()
    {
        switch(playerForm)
        {
            case 1: setImage("duck1"); break;
            case 2: setImage("duck2"); break;
            case 3: setImage("duck3"); break;
            default: setImage("duck1"); break;
        }
        stopLooping();
        isStill=true;
    }

    public void jump()
    {
        if (vertMoveMode==NOT_JUMPING)
        {
            vertMoveMode=RISING;
            upCount=0;
            if (isStill)
            {
                switch (playerForm)
                {
                    case 1: if (isFacingRight)
                                setImage("jumpRight1");
                            else
                                setImage("jumpLeft1");
                            break;
                    case 2: if (isFacingRight)
                                setImage("jumpRight2");
                            else
                                setImage("jumpLeft2");
                            break;
                    case 3: if (isFacingRight)
                                setImage("jumpRight3");
                            else
                                setImage("jumpLeft3");
                            break;
                    default: if (isFacingRight)
                                setImage("jumpRight1");
                            else
                                setImage("jumpLeft1");
                            break;
                }
            }
        }
    }

    public void setPlayerForm(int n)
    {
        playerForm=n;
    }

    public int getPlayerForm()
    {
        return playerForm;
    }

    public void transform2()
    {
        setImage("blank");
        Rectangle playerBox=getRectangle();
        playerBox.grow(-playerBox.width/3,0);

        if (playerBox.intersects(getRectangle()))
        {
            //playState.transform12(locx,locy+getHeight()/2);
            playState.transform2(locx,locy);
        }
    }

    public void transform3()
    {
        setImage("blank");
        Rectangle playerBox=getRectangle();
        playerBox.grow(-playerBox.width/3,0);

        if (playerBox.intersects(getRectangle()))
        {
            //playState.transform12(locx,locy+getHeight()/2);
            playState.transform3(locx,locy);
        }
    }

    

    public void hit()
    {
        
    }

    public void hitFloor()
    {
        
    }

    public void death()
    {
        
    }
}
